package com.example.mq.mqserver.core;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: DongGuoZhen
 * @Date: 2024/02/14/10:57
 * @Description: 表示一条要传递的消息
 * 一个message主要包含两个部分
 * 消息的属性部分
 * 消息的正文部分
 * 此处的message对象,是需要到网络上传输的,并且也要写入到文件中
 * 就需要对message进行序列化和反序列化
 * 此处使用标准库自带的序列化和反序列化
 */
public class Message implements Serializable {
    //这两个属性是message最核心的部分
    //消息的属性部分
    private BasicProperties basicProperties = new BasicProperties();
    //消息的正文部分
    private byte[] body;


    //下面的属性则是辅助用的属性
    //如果持久化的话,message最后会存储到文件中去
    //一个文件就会存储很多的消息,找到某个消息在文件中具体的位置,使用下列的偏移量
    // 使用前闭后开  [offsetBeg  offsetEnd) 包含offsetBeg,不包含offsetEnd
    //这两属性不需要序列化保持到文件中,因为消息写在文件中之后,位置就固定了.
    //这两个属性存在目的就是为了让内存中message对象,能够快速的找到硬盘上的message的位置
    //使用transient排除这个属性,不进行序列化
    private transient long offsetBeg = 0;  //消息数据开头距离文件开头的位置(字节)
    private transient long offsetEnd = 0;  //消息数据结尾距离文件开头的位置(字节)
    //使用这个属性表示该消息在文件是否为有效的消息(针对文件中的消息 逻辑删除)
    //ox1表示有效   0x0表示无效
    private byte isValid = 0x1;

    //创建一个工厂方法,让工厂方法帮我们封装一下创建message对象的过程
    //这个方法中创建的message对象自动生成唯一的messageId
    public static Message createMessageWithId(String routingKey,BasicProperties basicProperties,byte[] body) {
        Message message = new Message();
        if(basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        //万一routingKey和basicProperties冲突,以外面的为主
        message.setRoutingKey(routingKey);
        //此处生成的messageId 以 M- 作为前缀
        message.setMessageId("M-" + UUID.randomUUID());
        message.body = body;
        //此处只把body和basicProperties先设置出来,其他的都是在消息持久化的时候才会用到
        //此处只是在内存中创建一个message出来
        return message;
    }

    //针对消息属性的一些东西进行get和set
    public String getMessageId() {
        return basicProperties.getMessageId();
    }
    public void setMessageId(String messageId) {
         basicProperties.setMessageId(messageId);
    }
    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }
    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }
    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }
    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }

    //get and set
    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}